package org.rambadger.deployer.service;

import org.rambadger.deployer.utils.DeployerConstants;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Created with IntelliJ IDEA.
 * User: rtompkins
 * Date: 10/18/13
 * Time: 9:39 AM
 * To change this template use File | Settings | File Templates.
 */
@Service
public class QueryServerServiceImpl implements QueryServerService {

    private static final String CLASSNAME = QueryServerServiceImpl.class.getName();
    private static final Logger LOGGER = Logger.getLogger(CLASSNAME);

    @Override
    public Boolean stopQueryApp() {
        final String methodName = "stopQueryApp";
        LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Entry");

        try {
            LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Executing " + DeployerConstants.QUERY_STOP_COMMAND);
            Runtime.getRuntime().exec(DeployerConstants.QUERY_STOP_COMMAND);

            LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Exit");
            return Boolean.TRUE;

        } catch (Exception e) {
            LOGGER.logp(Level.SEVERE, CLASSNAME, methodName, "Failure in executing \"query.sh stop\" exception=" + e.getMessage());
            return Boolean.FALSE;
        }
    }

    @Override
    public Boolean startQueryApp() {
        final String methodName = "startQueryApp";
        LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Entry");

        try {
            LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Executing " + DeployerConstants.QUERY_START_COMMAND);
            Runtime.getRuntime().exec(DeployerConstants.QUERY_START_COMMAND);

            LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Exit");
            return Boolean.TRUE;

        } catch (Exception e) {
            LOGGER.logp(Level.SEVERE, CLASSNAME, methodName, "Failure in executing \"query.sh start\" exception=" + e.getMessage());
            return Boolean.FALSE;
        }
    }

    @Override
    public Boolean deployQueryAppFromNexus() {
        final String methodName = "deployQueryAppFromNexus";
        LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Entry");

        if (this.stopQueryApp().equals(Boolean.FALSE)) {
            LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Exit");
            return Boolean.FALSE;
        }

        if (this.getAndSaveLatestQueryArtifact().equals(Boolean.FALSE)) {
            LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Exit");
            return Boolean.FALSE;
        }

        if (this.startQueryApp().equals(Boolean.FALSE)) {
            LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Exit");
            return Boolean.FALSE;
        }

        LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Exit");
        return Boolean.TRUE;
    }

    @Override
    public Boolean restartQueryApp() {
        final String methodName = "restartQueryApp";
        LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Entry");

        if (this.stopQueryApp().equals(Boolean.FALSE)) {
            LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Exit");
            return Boolean.FALSE;
        }

        if (this.startQueryApp().equals(Boolean.FALSE)) {
            LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Exit");
            return Boolean.FALSE;
        }

        LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Exit");
        return Boolean.TRUE;
    }

    public Boolean getAndSaveLatestQueryArtifact() {
        final String methodName = "getAndSaveLatestQueryArtifact";
        LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Entry");

        try {
            URL url = new URL(DeployerConstants.LATEST_QUERY_ARTIFACT);

            InputStream inputStream = url.openStream();
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Opened connection to " + DeployerConstants.LATEST_QUERY_ARTIFACT);

            File file = new File(DeployerConstants.QUERY_JAR);
            OutputStream outputStream = new FileOutputStream(file);
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);

            byte [] buffer = new byte[4096];

            while (true) {
                int nRead = bufferedInputStream.read(buffer, 0, buffer.length);
                if (nRead <= 0) {
                    break;
                }
                bufferedOutputStream.write(buffer, 0, nRead);
            }

            LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Retrieved artifact to " + DeployerConstants.QUERY_JAR);

            bufferedOutputStream.flush();
            outputStream.close();
            inputStream.close();

            LOGGER.logp(Level.INFO, CLASSNAME, methodName, "Exit");
            return Boolean.TRUE;
        } catch (Exception e) {
            LOGGER.logp(Level.SEVERE, CLASSNAME, methodName, "Failure in retrieving query.jar exception=" + e.getMessage());
            return Boolean.FALSE;
        }
    }

}
